﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DDD.Core;
using FloatComparer = DDDTest.Helper.FloatComparer;

namespace DDDTest.Core {
    [TestClass]
    public class TestMeshBuilder {

        /// <summary>
        /// 球の作成テスト
        /// 垂直3, 水平4 
        /// </summary>
        /// <remarks>
        /// ファイルに出力された座標を確認すること。
        /// </remarks>
        [TestMethod]
        public void Test_CreateSphere_M3_N4 () {
            var mesh = MeshBuilder.CreateSphere (10, 3, 4, "v_Position", "v_Normal");

            var pos = mesh.VertexBuffer.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
            var nor = mesh.VertexBuffer.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
            var ibuf = mesh.IndexBuffer as IndexBuffer<int>;
            var indices = new int[ibuf.IndexCount];
            ibuf.Get (0, ibuf.PrimitiveCount, indices);
            var v = new float[3];

            using (var w = new StreamWriter ("Test-MeshBuilder-Sphere-N4-M3.txt")) {
                w.WriteLine ("Vertices = ");
                for (var i = 0; i < pos.VertexCount; i++) {
                    pos.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Indices = ");
                for (var i = 0; i < indices.Length; i += 3) {
                    w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                }
                w.WriteLine ("Normals = ");
                for (var i = 0; i < nor.VertexCount; i++) {
                    nor.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }

            }


        }

        /// <summary>
        /// 球の作成テスト
        /// 垂直5, 水平4
        /// </summary>
        /// <remarks>
        /// ファイルに出力された座標を確認すること。
        /// </remarks>
        [TestMethod]
        public void Test_CreateSphere_M5_N4 () {
            var mesh = MeshBuilder.CreateSphere (10, 5, 4, "v_Position", "v_Normal");

            var pos = mesh.VertexBuffer.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
            var nor = mesh.VertexBuffer.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
            var ibuf = mesh.IndexBuffer as IndexBuffer<int>;
            var indices = new int[ibuf.IndexCount];
            ibuf.Get (0, ibuf.PrimitiveCount, indices);

            var v = new float[3];
            using (var w = new StreamWriter ("Test-MeshBuilder-Sphere-N4-M5.txt")) {
                w.WriteLine ("Vertices = ");
                for (var i = 0; i < pos.VertexCount; i++) {
                    pos.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Indices = ");
                for (var i = 0; i < indices.Length; i += 3) {
                    w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                }
                w.WriteLine ("Normals = ");
                for (var i = 0; i < nor.VertexCount; i++) {
                    nor.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }

            }


        }

        /// <summary>
        /// 箱の作成テスト
        /// 垂直3、水平２分割
        /// </summary>
        /// <remarks>
        /// ファイルに出力された座標を確認すること。
        /// </remarks>
        [TestMethod]
        public void Test_CreateBox_M3_N2 () {
            var mesh = MeshBuilder.CreateBox (10, 3, 2, "v_Position", "v_Normal", "v_TexCoord");

            using (var w = new StreamWriter ("Test-MeshBuilder-Box-M3-N2.txt")) {
                for (var f = 0; f < 6; f++) {
                    w.WriteLine ("---------------------------------------------");
                    w.WriteLine ("Face = {0}", f);

                    var vbuf = mesh.GetVertexBuffer (f);
                    var pos = vbuf.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
                    var nor = vbuf.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
                    var tex = vbuf.GetAttribute ("v_TexCoord").VertexArray as VertexArray<float>;
                    var ibuf = mesh.GetIndexBuffer (f) as IndexBuffer<int>;
                    var indices = new int[ibuf.IndexCount];
                    ibuf.Get (0, ibuf.PrimitiveCount, indices);

                    var v = new float[3];
                    w.WriteLine ("Vertices = ");
                    for (var i = 0; i < pos.VertexCount; i++) {
                        pos.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                    }
                    w.WriteLine ("Normals = ");
                    for (var i = 0; i < nor.VertexCount; i++) {
                        nor.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                    }
                    w.WriteLine ("TexCoords = ");
                    for (var i = 0; i < tex.VertexCount; i++) {
                        tex.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3}", i, v[0], v[1]);
                    }
                    w.WriteLine ("Indices = ");
                    for (var i = 0; i < indices.Length; i += 3) {
                        w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                    }

                }
            }
        }

        /// <summary>
        /// 箱の作成テスト
        /// 垂直2、水平3分割
        /// </summary>
        /// <remarks>
        /// ファイルに出力された座標を確認すること。
        /// </remarks>
        [TestMethod]
        public void Test_CreateBox_M2_N3 () {
            var mesh = MeshBuilder.CreateBox (10, 2, 3, "v_Position", "v_Normal", "v_TexCoord");

            using (var w = new StreamWriter ("Test-MeshBuilder-Box-M2-N3.txt")) {
                for (var f = 0; f < 6; f++) {
                    w.WriteLine ("----------------------------------------");
                    w.WriteLine ("Face = {0}", f);

                    var vbuf = mesh.GetVertexBuffer (f);
                    var pos = vbuf.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
                    var nor = vbuf.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
                    var tex = vbuf.GetAttribute ("v_TexCoord").VertexArray as VertexArray<float>;
                    var ibuf = mesh.GetIndexBuffer (f) as IndexBuffer<int>;
                    var indices = new int[ibuf.IndexCount];
                    ibuf.Get (0, ibuf.PrimitiveCount, indices);

                    var v = new float[3];

                    w.WriteLine ("Vertices = ");
                    for (var i = 0; i < pos.VertexCount; i++) {
                        pos.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                    }
                    w.WriteLine ("Normals = ");
                    for (var i = 0; i < nor.VertexCount; i++) {
                        nor.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                    }
                    w.WriteLine ("TexCoords = ");
                    for (var i = 0; i < tex.VertexCount; i++) {
                        tex.Get (i, 1, v);
                        w.WriteLine ("{0} : {1:f3} {2:f3}", i, v[0], v[1]);
                    }
                    w.WriteLine ("Indices = ");
                    for (var i = 0; i < indices.Length; i += 3) {
                        w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                    }

                }

            }
        }

        [TestMethod]
        public void Test_CreateCylinder_M4_N3 () {
            var mesh = MeshBuilder.CreateCylinder (10, 10, 4, 3, "v_Position", "v_Normal");

            using (var w = new StreamWriter ("Test-MeshBuilder-Cylinder-M4-N3.txt")) {
                w.WriteLine ("----------------------------------------");

                var vbuf = mesh.GetVertexBuffer (0);
                var pos = vbuf.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
                var nor = vbuf.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
                var ibuf = mesh.GetIndexBuffer (0) as IndexBuffer<int>;
                var indices = new int[ibuf.IndexCount];
                ibuf.Get (0, ibuf.PrimitiveCount, indices);

                var v = new float[3];

                w.WriteLine ("Vertices = ");
                for (var i = 0; i < pos.VertexCount; i++) {
                    pos.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Normals = ");
                for (var i = 0; i < nor.VertexCount; i++) {
                    nor.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Indices = ");
                for (var i = 0; i < indices.Length; i += 3) {
                    w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                }

            }

        }

        [TestMethod]
        public void Test_CreateCylinder_M3_N4 () {
            var mesh = MeshBuilder.CreateCylinder (10, 10, 3, 4, "v_Position", "v_Normal");

            using (var w = new StreamWriter ("Test-MeshBuilder-Cylinder-M3-N4.txt")) {
                w.WriteLine ("----------------------------------------");

                var vbuf = mesh.GetVertexBuffer (0);
                var pos = vbuf.GetAttribute ("v_Position").VertexArray as VertexArray<float>;
                var nor = vbuf.GetAttribute ("v_Normal").VertexArray as VertexArray<float>;
                var ibuf = mesh.GetIndexBuffer (0) as IndexBuffer<int>;
                var indices = new int[ibuf.IndexCount];
                ibuf.Get (0, ibuf.PrimitiveCount, indices);

                var v = new float[3];

                w.WriteLine ("Vertices = ");
                for (var i = 0; i < pos.VertexCount; i++) {
                    pos.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Normals = ");
                for (var i = 0; i < nor.VertexCount; i++) {
                    nor.Get (i, 1, v);
                    w.WriteLine ("{0} : {1:f3} {2:f3} {3:f3}", i, v[0], v[1], v[2]);
                }
                w.WriteLine ("Indices = ");
                for (var i = 0; i < indices.Length; i += 3) {
                    w.WriteLine ("{0} : {1} {2} {3}", i / 3, indices[i], indices[i + 1], indices[i + 2]);
                }



            }

        }


    }  // TestMeshBuilder
}
